package com.aliyun.heiyu.powermaster.server.rbac.dao.impl;

import com.aliyun.heiyu.common.util.DateUtil;
import com.aliyun.heiyu.common.util.StringUtil;
import com.aliyun.heiyu.powermaster.proto.SafeAuditEntity;
import com.aliyun.heiyu.powermaster.server.rbac.contants.SafeSqlContant;
import com.aliyun.heiyu.powermaster.server.rbac.dao.SysSafeDAO;
import com.aliyun.heiyu.powermaster.server.rbac.enums.EventReadEnum;
import com.aliyun.heiyu.powermaster.server.rbac.object.dto.*;
import com.aliyun.heiyu.powermaster.server.rbac.object.entity.SysSafeAuditEntity;
import com.aliyun.heiyu.powermaster.server.rbac.utils.JdbcUtil;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

public class SysSafeDAOImpl implements SysSafeDAO {

    @Override
    public boolean insertSysSafe(SysSafeAuditEntity safeAuditEntity) {
        Object[] obj = new Object[10];
        obj[0] = new Date();
        obj[1] = safeAuditEntity.getEvent_type();
        if (StringUtil.isEmpty(safeAuditEntity.getUsername())
            && safeAuditEntity.getOpera_type() != 12) {
            return true;
        }
        if(safeAuditEntity.getOpera_type() != 12){
            obj[2] = safeAuditEntity.getUsername();
        }else {
            obj[2] = "";
        }
        if (StringUtils.isNotBlank(safeAuditEntity.getIp())) {
            obj[3] = safeAuditEntity.getIp();
        } else {
            obj[3] = "";
        }
        obj[4] = safeAuditEntity.getEvent_desc();
        obj[5] = safeAuditEntity.getEvent_result();
        obj[6] = safeAuditEntity.getEvent_state();
        obj[7] = EventReadEnum.NOT_READ.getCode();
        obj[8] = safeAuditEntity.getOpera_type();
        if (StringUtil.isEmpty(safeAuditEntity.getMenu_url())) {
            obj[9] = "";
        } else {
            obj[9] = safeAuditEntity.getMenu_url();
        }
        JdbcUtil.insert(SafeSqlContant.INSERT_SAFE, obj);
        return true;
    }

    @Override
    public List<SysSafeAuditEntity> selectSysSafe(SysSafeAuditEntity safeAuditEntity) {
        int count = 4;
        int addCount = 0;
        String startDate = DateUtil.dateToString(safeAuditEntity.getStartTime());
        String endDate = DateUtil.dateToString(safeAuditEntity.getEndTime());
        String username = safeAuditEntity.getUsername();
        int state = safeAuditEntity.getEvent_state();
        int order = safeAuditEntity.getOrder();
        int desc = safeAuditEntity.getDesc();
        int event_type = safeAuditEntity.getEvent_type();
        StringBuffer sql = new StringBuffer();
        int start = (safeAuditEntity.getPageNumber() - 1) * safeAuditEntity.getPageCount();
        int opera = safeAuditEntity.getOpera_type();
        sql.append(SafeSqlContant.SELECT_SAFES)
            .append(" where del_state = 1");
        if (opera != 0) {
            count++;
            sql.append(" and opera_type = ?");
        }
        if (event_type != 0) {
            count++;
            sql.append(" and event_type = ?");
        }
        if (state != 0) {
            count++;
            sql.append(" and event_state = ?");
        }else {
            sql.append(" and event_state not in (4,5,6) ");
        }
        if (!StringUtil.isEmpty(username)) {
            count++;
            sql.append(" and username like ?");
        }
        sql.append(" and collect_time between ? and ? ");
        sql.append(" order by ");
        if (2 == order) {
            sql.append(" username ");
        } else {
            sql.append(" collect_time ");
        }
        if (1 == desc) {
            sql.append(" ASC ");
        } else {
            sql.append(" DESC ");
        }
        sql.append(" limit ?,?");
        Object[] obj = new Object[count];
        if (opera != 0) {
            obj[addCount++] = opera;
        }
        if (event_type != 0) {
            obj[addCount++] = event_type;
        }
        if (state != 0) {
            obj[addCount++] = state;
        }
        if (!StringUtil.isEmpty(username)) {
            obj[addCount++] = "%" + username + "%";
        }
        obj[addCount++] = startDate;
        obj[addCount++] = endDate;
        obj[addCount++] = start;
        obj[addCount] = safeAuditEntity.getPageCount();
        return JdbcUtil.queryForList(sql.toString(), obj, SysSafeAuditEntity.class);
    }


    @Override
    public int selectSafeCount(SysSafeAuditEntity safe) {
        int count = 2;
        int addCount = 0;
        if (safe == null) {
            return 0;
        }
        StringBuffer sql = new StringBuffer();
        sql.append(SafeSqlContant.SELECT_SAFE_COUNT);
        int opera = safe.getOpera_type();
        int event_type = safe.getEvent_type();
        //时间段
        String startTime = DateUtil.dateToString(safe.getStartTime());
        String endTime = DateUtil.dateToString(safe.getEndTime());
        String username = safe.getUsername();
        int state = safe.getEvent_state();
        if (opera != 0) {
            count++;
            sql.append(" and opera_type = ?");
        }
        if (event_type != 0) {
            count++;
            sql.append(" and event_type = ?");
        }
        if (state != 0) {
            count++;
            sql.append(" and event_state = ?");
        }else {
            sql.append(" and event_state not in (4,5,6) ");
        }
        if (!StringUtil.isEmpty(username)) {
            count++;
            sql.append(" and username like ?");
        }
        sql.append(" and collect_time between ? and ? ");
        Object[] obj = new Object[count];
        if (opera != 0) {
            obj[addCount++] = opera;
        }
        if (event_type != 0) {
            obj[addCount++] = event_type;
        }
        if (state != 0) {
            obj[addCount++] = state;
        }
        if (!StringUtil.isEmpty(username)) {
            obj[addCount++] = "%" + username + "%";
        }
        obj[addCount++] = startTime;
        obj[addCount++] = endTime;
        Map<String, String> map = JdbcUtil.queryForMap(sql.toString(), obj);
        if (null == map) {
            return 0;
        }
        return Integer.parseInt(map.get("count"));
    }



    @Override
    public SafeDTO selectExecSafes(SafeDTO safeDTO) {
        String sql = "select max(collect_time) endTime,MIN(collect_time) startTime,count(id) count from sys_safe_audit where push =1 and event_state in(1,2)";
        return JdbcUtil.queryForBean(sql, null, SafeDTO.class);
    }

    @Override
    public  List<SafeDataDTO> safeReport(SysSafeAuditEntity safe) {
        Date startTime = safe.getStartTime();
        Date endTime = safe.getEndTime();
        int event_type = safe.getEvent_type();
        int count = 0;
        int addCount = 0;
        StringBuilder sql = new StringBuilder();
        sql.append("select t.username username,")
            .append(" count(if(opera_type = 1,t.id,null))  addLogCount,")
            .append(" count(if(opera_type = 2,t.id,null))  deleteLogCount,")
            .append("count(if(opera_type = 3,t.id,null))  updateLogCount,")
            .append(" count(if(opera_type = 4,t.id,null))  searchLogCount,")
            .append("  count(if(opera_type = 5,t.id,null))  importLogCount,")
            .append("  count(if(opera_type = 6,t.id,null))  exportLogCount,")
            .append(" count(if(opera_type = 7,t.id,null))  loginLogCount,")
            .append(" count(if(opera_type = 8,t.id,null))  outLogCount,")
            .append("  count(if(opera_type = 11,t.id,null))  beyond,")
            .append(" count(id)  totleCount,")
            .append(" count(if(event_type = 1,t.id,null))  sysLogCount,")
            .append(" count(if(event_type = 2,t.id,null))  busLogCount")
            .append(" from sys_safe_audit  t  where opera_type != 12");
        if (!StringUtil.isEmpty(safe.getUsername())) {
            count++;
            sql.append(" and t.username like ?");
        }
        if (event_type != 0) {
            count++;
            sql.append(" and t.event_type = ?");
        }
        if (null != startTime && null != endTime) {
            count++;
            count++;
            sql.append(" and  t.collect_time between ? and ?");
        }

        sql.append(" group by t.username ORDER BY t.username");
        Object[] obj = new Object[count];
        if (!StringUtil.isEmpty(safe.getUsername())) {
            obj[addCount++] = "%"+safe.getUsername()+"%";
        }
        if (event_type != 0) {
            obj[addCount++] = event_type;
        }
        if (null != startTime && null != endTime) {
            obj[addCount++] = startTime;
            obj[addCount++] = endTime;
        }
        List<SafeDataDTO> safeDataDTOS = JdbcUtil.queryForList(sql.toString(), obj, SafeDataDTO.class);
        return safeDataDTOS;
    }

    @Override
    public boolean updateSafePush(SafeDTO safeDTO) {
        String sql = "update sys_safe_audit set push = 2 where  collect_time BETWEEN ? and ?";
        Object[] obj = new Object[2];
        obj[0] = safeDTO.getStartTime();
        obj[1] = safeDTO.getEndTime();
        return JdbcUtil.update(sql, obj);
    }

    /**
     * 导出安全审计数据
     *
     * @param safeAuditEntity
     * @return
     */
    @Override
    public List<SysSafeAuditEntity> outputSysSafes(SysSafeAuditEntity safeAuditEntity) {
        String endDate = DateUtil.dateToString(safeAuditEntity.getEndTime());
        String startDate = DateUtil.dateToString(safeAuditEntity.getStartTime());
        String username = safeAuditEntity.getUsername();
        int state = safeAuditEntity.getEvent_state();
        StringBuffer sql = new StringBuffer();
        sql.append(SafeSqlContant.SELECT_SAFES);
        int count = 0;
        int addCount = 0;
        sql.append(" where event_state = 3");
        //1.判断时间段
        sql.append(" and collect_time between  ? and ? ");
        if(state != 0){
            count++;
            sql.append(" and event_state = ? ");
        }
        if(!StringUtil.isEmpty(username)){
            count++;
            sql.append(" and  username like ? ");
        }
        sql.append(" order by collect_time desc limit 10000");
        Object[] obj = new Object[2+count];
        obj[0] = startDate;
        obj[1] = endDate;
        if(state != 0){
            obj[2+addCount++] = state;
        }
        if(!StringUtil.isEmpty(username)){
            obj[2+addCount] = "%"+username+"%";
        }
        return JdbcUtil.queryForList(sql.toString(), obj, SysSafeAuditEntity.class);
    }

    /**
     * 导入安全审计数据
     *
     * @param safes
     * @return
     */
    @Override
    public int importSysSafes(List<SafeAuditEntity> safes) {
        if (CollectionUtils.isEmpty(safes)) {
            return 0;
        }
        List<SafeAuditEntity> safeList = new ArrayList<>();
        for (SafeAuditEntity sa : safes) {
            if (StringUtil.isEmpty(sa.getCollectTime()) || StringUtil.isEmpty(sa.getUsername())
                || StringUtil.isEmpty(sa.getEventDesc()) || StringUtil.isEmpty(sa.getIp())) {
                continue;
            }
            safeList.add(sa);
        }
        int count = 0;
        StringBuilder sql = new StringBuilder();
        sql.append("INSERT INTO sys_safe_audit");
        sql.append("(collect_time, event_type, username, ip, event_desc, event_result, del_state, event_state, push) values");
        Object[] obj = new Object[safeList.size() * 9];
        for (SafeAuditEntity safe : safeList) {
            sql.append("(?,?,?,?,?,?,?,?,?),");
            obj[count++] = safe.getCollectTime();
            obj[count++] = safe.getEventType();
            obj[count++] = safe.getUsername();
            obj[count++] = safe.getIp();
            obj[count++] = safe.getEventDesc();
            obj[count++] = safe.getEventResult();
            obj[count++] = 1;
            obj[count++] = safe.getEventState();
            obj[count++] = safe.getPush();
        }
        String resultSql = sql.substring(0, sql.length() - 1);
        JdbcUtil.insert(resultSql, obj);
        return count / 9;
    }

    /**
     * 查询安全审计数据
     *
     * @return
     */
    @Override
    public Map<String, String> qyerySafeData() {
        String sql = "{call state_grid.safeDatasize()}";
        String[] re = new String[4];
        re[0] = "table";
        re[1] = "count";
        re[2] = "dataSize";
        re[3] = "indexSize";
        return JdbcUtil.queryForProcedure(sql, re);
    }

    @Override
    public Map<String, String> findSafeCapacity() {
        Object[] kk = new Object[1];
        kk[0] = 1;
        String sql = "select * from sys_safe_capacity where id = ?";
        return JdbcUtil.queryForMap(sql, kk);
    }

    @Override
    public boolean updateSafeCapacity(Integer capacity) {
        Object[] kk = new Object[2];
        kk[0] = 1;
        kk[1] = capacity;
        String sql = "replace into sys_safe_capacity(id,capacity) values(?,?)";
        return JdbcUtil.update(sql, kk);
    }


}